package com.jdkreader.concurrency.concurrent.semaphore;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Semaphore;

/**
 * 对象池简单实现
 * @param <T>
 */
public class Pool<T> {

    private int size;

    private List<T> items=new ArrayList<T>();

    private volatile boolean[] checkOut;

    private Semaphore available;

    public Pool(Class<T> classObject,int size){
        this.size = size;
        available = new Semaphore(size,true);
        checkOut=new boolean[size];
        for(int i =0;i<size;i++){
            try {
                items.add(classObject.newInstance());
            }catch(Exception e){
                e.printStackTrace();
            }
        }
    }

    public T checkOut() throws InterruptedException{
        //获取许可
        available.acquire();
        return getItem();
    }

    private synchronized T getItem(){
        for(int i=0;i<size;i++){
            if (!checkOut[i]) {
               checkOut[i]=true; //检出标志置为true
               return items.get(i);
            }
        }
        return null; //checkOut()方法调用的available.acquire()保证这段程序不会运行到这里
    }

    /**
     * 用户使用完成，签回对象
     * @param item
     */
    public void checkIn(T item){
        if (releaseItem(item)) {
            available.release(); //释放一个许可证
        }
    }

    private synchronized boolean releaseItem(T item){
        int index=items.indexOf(item);
        if(index == -1){
            return false;
        }
        //对象被签出，需要执行签入操作
        if(checkOut[index]){
            checkOut[index]=false;
            return true;
        }
        return false;
    }


}
